package com.macro.mall.es.service.impl;

import com.macro.mall.common.domain.DocQueryReq;
import com.macro.mall.common.dto.DocDelDto;
import com.macro.mall.common.dto.DocDto;
import com.macro.mall.common.dto.ProductEsDto;
import com.macro.mall.es.service.EsDocService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Log4j2
public class EsDocServiceImpl implements EsDocService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Override
    public void batchSave(DocDto docDto) {
        //从docDto对象中获取文档数据datas和文档ID(idField)
        List<Map<String, Object>> datas = docDto.getDatas();
        String idField = docDto.getIdField();
        //判断集合是否为空
        if (CollectionUtils.isEmpty(datas)){
            throw new RuntimeException("文档数据不能为空");
        }
        //创建批量请求对象
        BulkRequest bulkRequest = new BulkRequest();
        //循环遍历文档数据datas
        for (Map<String, Object> data : datas) {
            //创建请求对象(指定文档名)
            IndexRequest indexRequest = new IndexRequest(docDto.getIndexName());
            //如果idField不为空，则从当前数据项中获取对应的ID值，并设置到indexRequest中
            if(StringUtils.isNotBlank(docDto.getIdField())){
                String id = data.get(idField).toString();
                indexRequest.id(id);
            }
            //传入文档数据
            indexRequest.source(data, XContentType.JSON);
            //添加到批量请求对象中
            bulkRequest.add(indexRequest);
        }
        try {
            //执行批量请求
            BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            //判断是否执行成功
            if (bulkResponse.hasFailures()){
                //获取失败原因
                String message = bulkResponse.buildFailureMessage();
                log.error("批量添加文档失败，失败原因：{}",message);
                throw new RuntimeException("批量添加文档失败");
            }
        } catch (IOException e) {
            log.error("批添失败，失败信息：{}",e);
            e.printStackTrace();
        }
    }

    @Override
    public void batchDelete(DocDelDto docDelDto) {
        //先从docDelDto对象中获取文档ID
        List<Integer> ids = docDelDto.getIds();
        //判断集合是否为空
        if (CollectionUtils.isEmpty(ids)){
            throw new RuntimeException("请去选择你要删除的文档ID");
        }
        //获取文档ID对应的索引名称
        String indexName = docDelDto.getIndexName();
        //创建删除请求对象
        DeleteRequest deleteRequest = new DeleteRequest(indexName, String.valueOf(ids));
        try {
            //把删除请求对象传入到批量请求对象中
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.add(deleteRequest);
            //执行删除请求
            restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("批删失败，失败信息：{}",e);
            e.printStackTrace();
        }
    }

    @Override
    public List<ProductEsDto> search(DocQueryReq docQueryReq) {
        //创建返回集合
        ArrayList<ProductEsDto> arrayList = new ArrayList<>();
        //获取索引名称
        String indexName = docQueryReq.getIndexName();
        //创建请求对象
        IndexRequest indexRequest = new IndexRequest(indexName);
        //创建多条件拼接对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //开始条件拼接
        if (StringUtils.isNotBlank(docQueryReq.getMatchQueryInfo().getKeyWord())){
            List<String> searchFieIds = docQueryReq.getMatchQueryInfo().getSearchFieIds();
            for (String searchFieId : searchFieIds) {
                boolQueryBuilder.should(QueryBuilders.matchQuery(searchFieId,docQueryReq.getMatchQueryInfo().getKeyWord()));
            }
        }


        return null;
    }
}
